package com.gzz.orchid.common.webmvc.graceful;

import io.undertow.UndertowOptions;
import io.undertow.server.DefaultByteBufferPool;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.servlet.api.*;
import io.undertow.util.Headers;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author higmd
 */
@Slf4j
@Configuration
@ConditionalOnClass(name = "io.undertow.Undertow")
public class UndertowConfiguration implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {

    // https 端口
    @Value("${server.port}")
    private Integer port;

    // 是否开启 https
    @Value("${server.ssl.enabled:false}")
    private Boolean sslEnable;


    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        log.info("Undertow 启动端口: {} SSL: {}", this.port, this.sslEnable);
        // 自定义线程池
        factory.addBuilderCustomizers(builder -> {
            builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
            //builder.setServerOption(UndertowOptions.ENABLE_STATISTICS, true);
            builder.setWorkerThreads(300); // 覆盖配置文件参数
            builder.setIoThreads(32);  //  提升IO吞吐量
            //builder.addHttpListener(9999,  "0.0.0.0");
            builder.setHandler(new HttpHandler() {
                @Override
                public void handleRequest(HttpServerExchange exchange) throws Exception {
                    exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                    exchange.getResponseSender().send("Https Hello World..");
                }
            });
        });
        //  添加自定义处理
        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
//            deploymentInfo
//                    .addOuterHandlerChainWrapper(new UndertowShutdownWrapper());
            WebSocketDeploymentInfo wsDeploymentInfo = new WebSocketDeploymentInfo();
            // 设置合理的参数
            wsDeploymentInfo.setBuffers(new DefaultByteBufferPool(true, 8192, 10, 10));
            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", wsDeploymentInfo);
        });
        //
        if (this.sslEnable) {
            //            Resource keyStore = new ClassPathResource("keystore.jks");
            //            factory.addBuilderCustomizers(builder -> builder.setSslContext(
            //                    SSLContextBuilder
            //                            .create()
            //                            .setKeyStoreType("PKCS12")
            //                            .setKeyManagerFactoryAlgorithm(KeyManagerFactory.getDefaultAlgorithm())
            //                            .setKeyStore(keyStore.getFile())
            //                            .setKeyStorePassword("yourpassword")
            //                            .build()
            //            ));

            factory.addDeploymentInfoCustomizers(new UndertowDeploymentInfoCustomizer() {
                @Override
                public void customize(DeploymentInfo deploymentInfo) {
                    SecurityConstraint securityConstraint = new SecurityConstraint();
                    WebResourceCollection webResourceCollection = new WebResourceCollection();
                    webResourceCollection.addUrlPattern("/*");
                    securityConstraint.addWebResourceCollection(webResourceCollection);
                    securityConstraint.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL);
                    securityConstraint.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT);
                    deploymentInfo.addSecurityConstraint(securityConstraint);
                    deploymentInfo.setConfidentialPortManager(new ConfidentialPortManager() {
                        @Override
                        public int getConfidentialPort(HttpServerExchange exchange) {
                            return port;
                        }
                    });
                }
            });
        }
    }

    //    @Bean
    //    public UndertowBuilderCustomizer customizer() {
    //        return builder ->{
    //            builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
    //            builder.addHttpListener(9990, "0.0.0.0");
    //            builder.setServerOption(UndertowOptions.MAX_CONCURRENT_REQUESTS_PER_CONNECTION, 1000);
    //            builder.setWorkerThreads(200) // 设置工作线程数，默认为 8
    //                    .setIoThreads(4); // 设置 I/O 线程数，默认为 CPU 核心数
    //        };
    //    }
    @Bean
    public UndertowShutdown shutdown() {
        return new UndertowShutdown();
    }

    @Bean
    public ActuatorHealthIndicator healthIndicator() {
        return new ActuatorHealthIndicator();
    }
}